package com.snail.common.datascope.utils;

import com.snail.common.core.constant.CommonConstants;
import com.snail.common.core.exception.ServiceException;
import com.snail.common.core.utils.StringUtils;
import com.snail.common.core.utils.sql.SqlUtil;
import com.snail.common.datascope.annotation.DataScope;
import com.snail.common.datascope.constants.DataScopeConstants;
import com.snail.common.security.utils.SecurityUtils;
import com.snail.system.api.domain.SysDept;
import com.snail.system.api.domain.SysRole;
import com.snail.system.api.model.LoginUser;
import lombok.SneakyThrows;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.HexValue;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description: 数据范围权限工具类
 * @Author: Snail
 * @CreateDate: 2023/8/11 14:35
 * @Version: V1.0
 */
public class DataScopeUtils {


    /**
     * 数据权限表达式
     *
     * @param dataScope 数据权限注解
     * @param aliasName 别名
     * @return 结果
     */
    @SneakyThrows
    public static Expression authExpression(DataScope dataScope,String aliasName) {
        //如果注解指定了别名就用注解指定的,没有指定就获取sql片段中的
        String alias = StringUtils.defaultIfBlank(dataScope.alias(),aliasName);
        //1.获取当前登录人
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if(loginUser == null){
            throw new ServiceException("请先登录系统!");
        }
        //2.当前登录人的角色
        List<SysRole> sysRoles = loginUser.getSysRoles();
        //当前登录人部门
        SysDept sysDept = loginUser.getSysDept();
        //角色数据权限范围
        Set<String> dataScopeSet = sysRoles.stream().map(SysRole::getDataScope).collect(Collectors.toSet());
        //当前登录人角色部门权限
        List<String> deptPermission = loginUser.getDeptPermission();
        String deptIds = deptPermission.stream().map(String::valueOf).collect(Collectors.joining(CommonConstants.SPLIT_CHAR_1));
        StringBuilder sql = new StringBuilder();
        //全部数据权限
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_ALL)) {
            return null;
        }
        //当前组织及下属组织和自定义组织权限
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_DEPT_AND_CHILD) && dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_CUSTOM)) {
            OrExpression orExpression = new OrExpression();
            //当前组织及下属组织
            orExpression.setLeftExpression(SqlUtil.likeExpression(alias,dataScope.deptFullColumn(),sysDept.getDeptFullId()));
            //自定义组织
            orExpression.setRightExpression(SqlUtil.inExpression(alias,dataScope.deptColumn(),deptIds));
            return orExpression;
        }
        //当前组织及下属组织
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_DEPT_AND_CHILD)) {
            return SqlUtil.likeExpression(alias,dataScope.deptFullColumn(),sysDept.getDeptFullId());
        }
        //当前组织和自定义组织权限
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_DEPT) && dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_CUSTOM)) {
            OrExpression orExpression = new OrExpression();
            //当前组织
            orExpression.setLeftExpression(SqlUtil.eqExpression(alias,dataScope.deptColumn(),sysDept.getDeptId()));
            //自定义组织
            orExpression.setRightExpression(SqlUtil.inExpression(alias, dataScope.deptColumn(), deptIds));
            return orExpression;
        }
        //当前组织
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_DEPT)) {
            return SqlUtil.eqExpression(alias, dataScope.deptColumn(), sysDept.getDeptId());
        }
        //自定义组织权限和本人权限
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_CUSTOM) && dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_SELF)) {
            OrExpression orExpression = new OrExpression();
            //当前组织
            orExpression.setLeftExpression(SqlUtil.inExpression(alias, dataScope.deptColumn(), deptIds));
            //本人的数据权限
            orExpression.setRightExpression(SqlUtil.eqExpression(alias,dataScope.userColumn(),loginUser.getUserId()));
            return orExpression;
        }
        //自定义组织权限
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_CUSTOM)) {
            return SqlUtil.inExpression(alias, dataScope.deptColumn(), deptIds);
        }
        //本人的数据权限
        if (dataScopeSet.contains(DataScopeConstants.DATA_SCOPE_SELF)) {
            return SqlUtil.eqExpression(alias,dataScope.userColumn(),loginUser.getUserId());
        }
        //没有任何数据权限
        return new HexValue("1=2");
    }
}
